package com.evan.common.online.object;

import com.alibaba.fastjson.JSONObject;
import com.evan.common.core.object.CallResult;
import com.evan.common.core.object.TypedCallResult;
import com.evan.common.online.dto.OnlineFilterDto;
import com.evan.common.online.model.OnlineTable;

import java.util.List;
import java.util.Map;

/**
 * 在线表单脚本可执行接口，所有在线表单的后台Groovy脚本类都需要继承该接口。
 *
 * @author evan
 * @date 2024-04-20
 */
public interface OnlineScriptExecutable {

    /**
     * 主从表数据级联插入之前执行的脚本操作。
     *
     * @param masterTable          主表对象。
     * @param masterData           主表数据。
     * @param slaveTableAndDataMap 从表对象和数据的映射关系。
     * @return 返回调用结果对象，成功则继续执行，否则调用时会抛出异常，异常信息为具体的错误信息。
     */
    default CallResult beforeInsertWithRelation(
            OnlineTable masterTable, JSONObject masterData, Map<OnlineTable, List<JSONObject>> slaveTableAndDataMap) {
        return CallResult.ok();
    }

    /**
     * 表数据插入之前执行的脚本操作。
     *
     * @param table 表对象。
     * @param data  表数据。
     * @return 返回调用结果对象，成功则继续执行，否则调用时会抛出异常，异常信息为具体的错误信息。
     */
    default CallResult beforeInsert(OnlineTable table, JSONObject data) {
        return CallResult.ok();
    }

    /**
     * 表数据插入之后执行的脚本操作。
     *
     * @param table 表对象。
     * @param data  表数据。
     */
    default void afterInsert(OnlineTable table, JSONObject data) {
    }

    /**
     * 表数据批量插入之前执行的脚本操作。
     *
     * @param table    表对象。
     * @param dataList 数据列表。
     * @return 返回调用结果对象。会携带修改后的数据列表。
     */
    default TypedCallResult<List<JSONObject>> beforeBatchInsert(OnlineTable table, List<JSONObject> dataList) {
        return TypedCallResult.ok(dataList);
    }

    /**
     * 主从表数据级联更新之前执行的脚本操作。
     *
     * @param masterTable          主表对象。
     * @param masterData           主表数据。
     * @param slaveTableAndDataMap 从表对象和数据的映射关系。
     * @return 返回调用结果对象，成功则继续执行，否则调用时会抛出异常，异常信息为具体的错误信息。
     */
    default CallResult beforeUpdateWithRelation(
            OnlineTable masterTable, JSONObject masterData, Map<OnlineTable, List<JSONObject>> slaveTableAndDataMap) {
        return CallResult.ok();
    }

    /**
     * 表数据更新之前执行的脚本操作。
     *
     * @param table 表对象。
     * @param data  表数据。
     * @return 返回调用结果对象，成功则继续执行，否则调用时会抛出异常，异常信息为具体的错误信息。
     */
    default CallResult beforeUpdate(OnlineTable table, JSONObject data) {
        return CallResult.ok();
    }

    /**
     * 表数据更新之后执行的脚本操作。
     *
     * @param table 表对象。
     * @param data  表数据。
     */
    default void afterUpdate(OnlineTable table, JSONObject data) {
    }

    /**
     * 表数据删除之前执行的脚本操作。
     *
     * @param table        表对象。
     * @param data         表数据。
     * @param logicDeleted 是否逻辑删除。
     * @return 返回调用结果对象，成功则继续执行，否则调用时会抛出异常，异常信息为具体的错误信息。
     */
    default CallResult beforeDelete(OnlineTable table, JSONObject data, boolean logicDeleted) {
        return CallResult.ok();
    }

    /**
     * 表数据删除之后执行的脚本操作。
     *
     * @param table        表对象。
     * @param data         表数据。
     * @param logicDeleted 是否逻辑删除。
     */
    default void afterDelete(OnlineTable table, JSONObject data, boolean logicDeleted) {
    }

    /**
     * 表数据查询之前执行的脚本操作。
     *
     * @param table      表对象。
     * @param filterList 过滤条件。如果有新的过滤条件，可直接添加到该过滤列表。
     */
    default void beforeSelect(OnlineTable table, List<OnlineFilterDto> filterList) {
    }

    /**
     * 表数据查询之后执行的脚本操作。
     *
     * @param table      表对象。
     * @param resultList 查询结果。如果有修改，可直接在当前参数修改后即可生效。
     */
    default void afterSelect(OnlineTable table, List<Map<String, Object>> resultList) {
    }
}
